"""节点状态管理相关的类定义。"""

import logging
from abc import ABC, abstractmethod
from enum import Enum, auto
from typing import Optional, Dict, Any

from 程序核心代码.ast节点.节点定义.基础定义.节点异常定义 import 节点状态异常

logger = logging.getLogger(__name__)

class 节点状态类型(Enum):
    """节点状态枚举。"""
    初始化 = auto()
    正常 = auto()
    警告 = auto()
    错误 = auto()
    禁用 = auto()

class 节点状态(ABC):
    """节点状态基类，定义状态接口。"""
    
    def __init__(self, 状态管理器: '节点状态管理器'):
        self.状态管理器 = 状态管理器
        
    @abstractmethod
    def 进入状态(self) -> None:
        """进入当前状态时的处理。"""
        pass
        
    @abstractmethod
    def 离开状态(self) -> None:
        """离开当前状态时的处理。"""
        pass
        
    @abstractmethod
    def 更新状态(self) -> None:
        """更新当前状态。"""
        pass

class 初始化状态(节点状态):
    """节点初始化状态。"""
    
    def 进入状态(self) -> None:
        logger.debug("节点进入初始化状态")
        self.状态管理器.节点.清除错误信息()
        self.状态管理器.节点.清除警告信息()
        
    def 离开状态(self) -> None:
        logger.debug("节点离开初始化状态")
        
    def 更新状态(self) -> None:
        # 检查节点是否已完成初始化
        if self.状态管理器.节点._ast节点 is not None:
            self.状态管理器.切换状态(节点状态类型.正常)

class 正常状态(节点状态):
    """节点正常状态。"""
    
    def 进入状态(self) -> None:
        logger.debug("节点进入正常状态")
        self.状态管理器.节点.清除错误信息()
        self.状态管理器.节点.清除警告信息()
        
    def 离开状态(self) -> None:
        logger.debug("节点离开正常状态")
        
    def 更新状态(self) -> None:
        if self.状态管理器.节点.错误信息:
            self.状态管理器.切换状态(节点状态类型.错误)
        elif self.状态管理器.节点.警告信息:
            self.状态管理器.切换状态(节点状态类型.警告)

class 警告状态(节点状态):
    """节点警告状态。"""
    
    def 进入状态(self) -> None:
        logger.debug(f"节点进入警告状态: {self.状态管理器.节点.警告信息}")
        
    def 离开状态(self) -> None:
        logger.debug("节点离开警告状态")
        
    def 更新状态(self) -> None:
        if self.状态管理器.节点.错误信息:
            self.状态管理器.切换状态(节点状态类型.错误)
        elif not self.状态管理器.节点.警告信息:
            self.状态管理器.切换状态(节点状态类型.正常)

class 错误状态(节点状态):
    """节点错误状态。"""
    
    def 进入状态(self) -> None:
        logger.debug(f"节点进入错误状态: {self.状态管理器.节点.错误信息}")
        
    def 离开状态(self) -> None:
        logger.debug("节点离开错误状态")
        
    def 更新状态(self) -> None:
        if not self.状态管理器.节点.错误信息:
            if self.状态管理器.节点.警告信息:
                self.状态管理器.切换状态(节点状态类型.警告)
            else:
                self.状态管理器.切换状态(节点状态类型.正常)

class 禁用状态(节点状态):
    """节点禁用状态。"""
    
    def 进入状态(self) -> None:
        logger.debug("节点进入禁用状态")
        self.状态管理器.节点.是否显示 = False
        
    def 离开状态(self) -> None:
        logger.debug("节点离开禁用状态")
        self.状态管理器.节点.是否显示 = True
        
    def 更新状态(self) -> None:
        pass

class 节点状态管理器:
    """节点状态管理器，负责管理节点的状态转换。"""
    
    def __init__(self, 节点: Any):
        self.节点 = 节点
        self._状态映射: Dict[节点状态类型, 节点状态] = {
            节点状态类型.初始化: 初始化状态(self),
            节点状态类型.正常: 正常状态(self),
            节点状态类型.警告: 警告状态(self),
            节点状态类型.错误: 错误状态(self),
            节点状态类型.禁用: 禁用状态(self)
        }
        self._当前状态: Optional[节点状态] = None
        self.切换状态(节点状态类型.初始化)
        
    @property
    def 当前状态类型(self) -> 节点状态类型:
        """获取当前状态类型。"""
        for 状态类型, 状态 in self._状态映射.items():
            if 状态 is self._当前状态:
                return 状态类型
        return 节点状态类型.错误
        
    def 切换状态(self, 新状态类型: 节点状态类型) -> None:
        """切换到新状态。
        
        Args:
            新状态类型: 要切换到的新状态类型
            
        Raises:
            节点状态异常: 当状态切换失败时抛出
        """
        try:
            新状态 = self._状态映射[新状态类型]
            if 新状态 is not self._当前状态:
                logger.info(f"节点状态切换: {self.当前状态类型} -> {新状态类型}")
                if self._当前状态:
                    self._当前状态.离开状态()
                self._当前状态 = 新状态
                self._当前状态.进入状态()
        except KeyError as e:
            raise 节点状态异常(f"无效的状态类型: {新状态类型}") from e
        except Exception as e:
            raise 节点状态异常(f"状态切换失败: {str(e)}") from e
            
    def 更新状态(self) -> None:
        """更新当前状态。"""
        if self._当前状态:
            self._当前状态.更新状态()
            
    def 获取状态信息(self) -> Dict[str, Any]:
        """获取当前状态的详细信息。
        
        Returns:
            Dict[str, Any]: 包含状态信息的字典
        """
        return {
            "状态类型": self.当前状态类型,
            "错误信息": self.节点.错误信息,
            "警告信息": self.节点.警告信息,
            "是否显示": self.节点.是否显示
        } 